/**
* \file DGVPlot.h
*
* \brief This file defines the class for doing 1D plots using only Qt and QWT.
* \author Shekhar S. Chandra, 2008-2009
*
* This file is part of DGV Library.
*
* DGV is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DGV is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with DGV.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DGVPLOT_H
#define DGVPLOT_H

#include <qwt_plot.h> //Plotter
#include <qwt_plot_curve.h> //Holds Data

#include "DGVAliases.h"

/*!
    \class DGVPlot
    \brief This class handles 1D plots of data using Qwt.
    \author Shekhar S. Chandra, 2008-2009

    It handles multiple 1D plots on the same plot and uses a generated scale and legend.

    Usage Example 1:
    \code
    DGVPlot *rowPlot = new DGVPlot;
    Array<double,1> uniqueRow(prime), op(prime);
    firstIndex x;
    int prime = 13;

    uniqueRow = sin(4.0*x/prime);

    op = x;
    rowPlot->setName("Nth Ghost");
    rowPlot->createCurvePlot(op,uniqueRow,"Nth Ghost");
    rowPlot->show();
    \endcode

    Usage Example 2:
    \code
    DGVPlot *rowPlot = new DGVPlot;
    Array<double,1> uniqueRow(prime), op(prime);
    firstIndex x;
    int prime = 13;

    uniqueRow = sin(4.0*x/prime);

    op = x;
    rowPlot->setName("Nth Ghost");
    rowPlot->setData(op,uniqueRow);
    rowPlot->generatePlot();
    rowPlot->show();
    \endcode

    If memory conscious, use example 1 instead of example 2.
*/
class DGV_EXPORT DGVPlot : public QwtPlot
{
    Q_OBJECT //!< \todo Q_OBJECT Needed for connections, DEFINES    += QT_DLL QWT_DLL needed in project file

public:
    /*!
    \fn DGVPlot::DGVTable(QWidget *parent = 0)
    \brief The standard constructor
    */
    DGVPlot(QWidget *parent = 0);
    /*!
    \fn DGVPlot::~DGVPlot()
    \brief The standard destructor
    */
    virtual ~DGVPlot();

    /**
        \fn DGVPlot::setName(QString filename)
        \brief Sets the name of the plot.
    */
    void setName(QString filename);
    /**
        \fn DGVPlot::setToLinePlot(bool lines)
        \brief Sets the style of the plot to lines (true) or points/dots (false).
    */
    void setToLinePlot(bool lines);
    /**
        \fn DGVPlot::setData(Array<imageType,1> &xData, Array<imageType,1> &yData)
        \brief Sets the data for the plot. Call generatePlot() after this to create the plot.
    */
    void setData(Array<imageType,1> &xData, Array<imageType,1> &yData);
    /**
        \fn DGVPlot::setData(Array< Array<imageType,1>, 1 > &xData, Array< Array<imageType,1>, 1 > &yData)
        \brief Sets the data for the plot. Call generatePlot() after this to create the plot.
    */
    void setData(Array< Array<imageType,1>, 1 > &xData, Array< Array<imageType,1>, 1 > &yData);
    /**
    \fn DGVPlot::createCurvePlots(Array< Array<imageType,1>, 1 > &xData, Array< Array<imageType,1>, 1 > &yData, QString plotTitle)
    \brief Creates curve plots of the rows of data provided.
    */
    virtual void createCurvePlots(Array< Array<imageType,1>, 1 > &xData, Array< Array<imageType,1>, 1 > &yData, QString plotTitle);
    virtual void createCurvePlot(Array<imageType,1> xData, Array<imageType,1> yData, QString plotTitle);
    /**
        \fn DGVPlot::generatePlot()
        \brief Generates the plot from the stored data.
    */
    void generatePlot();

    /**
        \fn DGVPlot::loadGNU(QString filename)
        \brief Loads a 2D GNU Plot data file.
    */
    bool loadGNU(QString filename);
    /**
        \fn DGVPlot::saveGNU(QString filename)
        \brief Saves the data as a 2D GNU Plot data file.
    */
    bool saveGNU(QString filename);

    void setRenderAntialiased()
    {   antialiased = true; }
    /*!
        \fn DGVPlot::strippedName()
        \brief Returns the stripped (path removed) name of the plot.
    */
    QString strippedName();
    /*!
        \fn DGVPlot::strippedNamePrefix()
        \brief Returns the stripped (path removed) name of the plot with "Plot" prefix.
    */
    QString strippedNamePrefix();

public slots:
    /*!
        \fn DGVPlot::save()
        \brief Saves the plot.
    */
    void save();
    /*!
        \fn DGVPlot::xLabel()
        \brief Ask for x-label
    */
    void xLabel();
    /*!
        \fn DGVPlot::yLabel()
        \brief Ask for y-label
    */
    void yLabel();
    /*!
        \fn DGVPlot::titleLabel()
        \brief Ask for title label
    */
    void titleLabel();
    /*!
        \fn DGVPlot::rescaleAxis(const int axis)
        \brief Rescale axis
    */
    void rescaleAxis(const int axis);
    /*!
        \fn DGVPlot::rescaleXAxis()
        \brief Rescale x-axis
    */
    void rescaleXAxis();
    /*!
        \fn DGVPlot::rescaleYAxis()
        \brief Rescale y-axis
    */
    void rescaleYAxis();
    /*!
        \fn DGVPlot::toggleLinePlot()
        \brief Toggles whether plot is a line or points plot
    */
    void toggleLinePlot();
    /*!
        \fn DGVPlot::renameData()
        \brief Renames the plot data.
    */
    void renameData();

signals:
    /*!
        \fn DGVPlot::nameChanged(const QString newName)
        \brief Send signal that the window has been renamed.
    */
    void nameChanged(const QString newName);

protected:
    QString name; //!< Name of the plot.
    bool loaded; //!< Data loaded into arrays
    bool linePlot; //!< Is plot shown a line plot?

    //-------------
    QAction *saveAct; //!< Saves window
    //------------------
	QAction *xLabelAct; //!< x label
	QAction *yLabelAct; //!< y label
	QAction *titleAct; //!< Title
	QAction *xScaleAct; //!< x rescale
	QAction *yScaleAct; //!< y rescale
	QAction *linePlotAct; //!< toggle line plot to point plot?
    //-------------
    QAction *renameAct; //!< Renames window
    QAction *refreshAct; //!< Renames window
    QAction *closeAct; //!< Closes window

    bool antialiased;

    Array< Array<imageType,1>, 1 > xArray;
    Array< Array<imageType,1>, 1 > yArray;
    int plotSize;

    Array<QwtPlotCurve*, 1> curves;

    virtual void contextMenuEvent(QContextMenuEvent *event);
};

#endif // DGVPLOT_H
